package com.example.demo.config.response;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

/**
 * @author
 * 返回实体处理类
 */
@Slf4j
@ControllerAdvice
public class ResponseResultHandler implements ResponseBodyAdvice<Object> {

    /**
     * 标记
     */
    private static final String RESPONSE_RESULT_ANN = "RESPONSE_RESULT_ANN";

    /**
     * 空方法
     */
    private static final String VOID_METHOD_TYPE = "void";

    /**
     * 分隔符号
     */
    private static final String CLASS_SEPARATION = ".";

    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = Objects.requireNonNull(requestAttributes).getRequest();
        // 判断请求，是否有标记
        RestController responseResult = (RestController) request.getAttribute(RESPONSE_RESULT_ANN);
        return responseResult != null;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType,
                                  Class<? extends HttpMessageConverter<?>> aClass,
                                  ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        log.info("进入 返回体 重写格式 处理中...");
        if (body instanceof ErrorInfo){
            return body;
        }

        // 方法返回类型
        final String returnMethodType = methodParameter.getMethod().getName();
        if (VOID_METHOD_TYPE.equals(returnMethodType)){
            return Result.success();
        }

        // 判断是否非json类型的返回值
        if (!mediaType.equals(MediaType.APPLICATION_JSON)){
            return JSON.toJSONString(Result.success(body), SerializerFeature.WriteMapNullValue);
        }

        // 如果是Result对象则直接返回
        if (body instanceof Result){
            return body;
        }

        // 结果成功
        Result result = Result.success(body);
        log.info("=========================================== End ===========================================" + System.lineSeparator());
        return result;
    }

}